# -*- coding: utf-8 -*-
# Author: xiantingDeng
# File: 01_xpath的使用.py
# Time: 17:09

# 安装：
# pip install lxml

'''
表达式	描述
nodename	选取此节点的所有子节点。
/	从当前节点选取直接子节点
//	从匹配选择的当前节点选择所有子孙节点，而不考虑它们的位置
.	选取当前节点。
..	选取当前节点的父节点。
@	选取属性。


运算符	描述	实例	返回值
¦	计算两个节点集	//book ¦ //cd	返回所有拥有 book 和 cd 元素的节点集
+	加法	6 + 4	10
-	减法	6 - 4	2
*	乘法	6 * 4	24
div	除法	8 div 4	2
=	等于	price=9.80	如果 price 是 9.80，则返回 true。、\n 如果 price 是 9.90，则返回 false。
!=	不等于	price!=9.80	如果 price 是 9.90，则返回 true。\n 如果 price 是 9.80，则返回 false。
<	小于	price<9.80	如果 price 是 9.00，则返回 true。\n 如果 price 是 9.90，则返回 false。
<=	小于或等于	price<=9.80	如果 price 是 9.00，则返回 true。\n 如果 price 是 9.90，则返回 false。
>	大于	price>9.80	如果 price 是 9.90，则返回 true。\n如果 price 是 9.80，则返回 false。
>=	大于或等于	price>=9.80	如果 price 是 9.90，则返回 true。\n如果 price 是 9.70，则返回 false。
or	或	price=9.80 or price=9.70	如果 price 是 9.80，则返回 true。\n如果 price 是 9.50，则返回 false。
and	与	price>9.00 and price<9.90	如果 price 是 9.80，则返回 true。\n如果 price 是 8.50，则返回 false。
mod	计算除法的余数	5 mod 2	1
'''


text = '''
<!DOCTYPE html>
<html>
<head>
    <title>我的网页</title>
</head>
<body>
    <h3 id="hid">我的常用链接</h3>
    <ul>
        <li class="item-0"><a href="http://www.baidu.com">百度</a></li>
        <li class="item-1 shop"><a href="http://www.jd.com">京东</a></li>
        <li class="item-2"><a href="http://www.sohu.com">搜狐</a></li>
        <li class="item-3"><a href="http://www.sina.com">新浪</a></li>
        <li class="item-4 shop"><a href="http://www.taobao.com">淘宝</a></li>
    </ul>

</body>
</html>
'''

from lxml import etree

html = etree.HTML(text)
result = html.xpath("//*")
for t in result:
    print(t.tag,end= " ")

print("\n","-"*50)

# 获取节点
result = html.xpath("//li") # 获取所有li节点
result = html.xpath("//li/a") # 获取所有li节点下的所有直接a子节点
result = html.xpath("//ul//a") # 效果同上（ul下所有子孙节点）
result = html.xpath("//a/..") #获取所有a节点的父节点
print(result)

# 获取属性和文本内容
result = html.xpath("//li/a/@href") #获取所有li下所有直接子a节点的href属性值
result = html.xpath("//li/a/text()") #获取所有li下所有直接子a节点内的文本内容
print(result) #['百度', '京东', '搜狐', '新浪', '淘宝']

result = html.xpath("//li/a[@class]/text()") #获取所有li下所有直接含有class属性子a节点内的文本内容
print(result) #['百度', '搜狐', '新浪']

#获取所有li下所有直接含有class属性值为aa的子a节点内的文本内容
result = html.xpath("//li/a[@class='aa']/text()")
print(result) #['搜狐', '新浪']


#获取class属性值中含有shop的li节点下所有直接a子节点内的文本内容
result = html.xpath("//li[contains(@class,'shop')]/a/text()")
print(result) #['搜狐', '新浪']

# 按序选择
result = html.xpath("//li[1]/a/text()") # 获取每组li中的第一个li节点里面的a的文本
result = html.xpath("//li[last()]/a/text()") # 获取每组li中最后一个li节点里面的a的文本
result = html.xpath("//li[position()<3]/a/text()") # 获取每组li中前两个li节点里面的a的文本
result = html.xpath("//li[last()-2]/a/text()") # 获取每组li中倒数第三个li节点里面的a的文本
print(result)

print("--"*30)
# 节点轴选择
result = html.xpath("//li[1]/ancestor::*") # 获取li的所有祖先节点
result = html.xpath("//li[1]/ancestor::ul") # 获取li的所有祖先中的ul节点
result = html.xpath("//li[1]/a/attribute::*") # 获取li中a节点的所有属性值
result = html.xpath("//li/child::a[@href='http://www.sohu.com']") #获取li子节点中属性href值的a节点
result = html.xpath("//body/descendant::a") # 获取body中的所有子孙节点a
print(result)

result = html.xpath("//li[3]") #获取li中的第三个节点
result = html.xpath("//li[3]/following::li") #获取第三个li节点之后所有li节点
result = html.xpath("//li[3]/following-sibling::*") #获取第三个li节点之后所有同级li节点
for v in result:
    print(v.find("a").text)